package myJs.user.predict

import myJs.Implicits._
import myJs.{PredictResult, Tool}
import myJs.Utils._
import myJs.api.Api
import myJs.cps.{FormGroupInlineCp, NumInputCp, PureInputCp, Style}
import myJs.myPkg.{SwalOptions, swal}
import myJs.myPkg.jquery.$
import myJs.myPkg.reactHookForm._
import org.scalajs.dom.{FormData, document, html}
import slinky.core.FunctionalComponent
import slinky.core.annotations.react
import slinky.core.facade.Hooks.{useEffect, useState}
import slinky.core.facade.{Fragment, React}
import slinky.web.html._

import scala.collection.immutable.SeqMap
import scala.concurrent.{Future, Promise}
import scala.scalajs.js
import scala.scalajs.js.Dynamic.{global => g}
import scala.scalajs.js.timers.SetTimeoutHandle
import scala.scalajs.js.{JSON, |}
import org.scalajs.macrotaskexecutor.MacrotaskExecutor.Implicits._
import com.softwaremill.quicklens._
import shared.pojo.Pojo.predict._

/**
 * Created by yz on 21/1/2022
 */
@react object Cp {


  case class Props(
                  )

  val component = FunctionalComponent[Props] { props =>

    val (data, setData) = useState(PredictData())

    val useForm = ReactHookForm.useForm(UseFormOptions(mode = "onChange"))

    object FTool {

      def sampleIdChange = (v: String) => {
        val newData = data.modify(_.sampleId).setTo(v)
        setData(newData)
      }

      def nameChange = (v: String) => {
        val newData = data.modify(_.name).setTo(v)
        setData(newData)
      }

      def ageChange = (v: String) => {
        val newData = data.modify(_.age).setTo(v)
        setData(newData)
      }

      def astChange = (v: String) => {
        val newData = data.modify(_.ast).setTo(v)
        setData(newData)
      }

      def altChange = (v: String) => {
        val newData = data.modify(_.alt).setTo(v)
        setData(newData)
      }

      def pltChange = (v: String) => {
        val newData = data.modify(_.plt).setTo(v)
        setData(newData)
      }

      def tyrChange = (v: String) => {
        val newData = data.modify(_.tyr).setTo(v)
        setData(newData)
      }

      def tcaChange = (v: String) => {
        val newData = data.modify(_.tca).setTo(v)
        setData(newData)
      }

      def pheChange = (v: String) => {
        val newData = data.modify(_.phe).setTo(v)
        setData(newData)
      }

      def trpChange = (v: String) => {
        val newData = data.modify(_.trp).setTo(v)
        setData(newData)
      }

      def valineChange = (v: String) => {
        val newData = data.modify(_.valine).setTo(v)
        setData(newData)
      }

      def caChange = (v: String) => {
        val newData = data.modify(_.ca).setTo(v)
        setData(newData)
      }

      def metChange = (v: String) => {
        val newData = data.modify(_.met).setTo(v)
        setData(newData)
      }

      def gcaChange = (v: String) => {
        val newData = data.modify(_.gca).setTo(v)
        setData(newData)
      }

      def gcdcaChange = (v: String) => {
        val newData = data.modify(_.gcdca).setTo(v)
        setData(newData)
      }

      def tcdcaChange = (v: String) => {
        val newData = data.modify(_.tcdca).setTo(v)
        setData(newData)
      }

      def myRunBefore = () => {
        Api.user.getLimit.map { response =>
          if (!response) {
            val options = SwalOptions(title = "Error", text = "您无此权限使用该系统，请与管理员联系！", `type` = "error")
            swal(options)
            $("#myRun").attr("disabled", true)
          } else {
            FTool.myRun
          }
        }
        ()
      }

      def myRun = {
        val index = layer.alert(element, layerOptions)
        Api.predict.predict(data).map { response =>
          layer.close(index)
          if (!response.valid) {
            swal(SwalOptions(title = "错误", text = response.message, `type` = "error"))
            $("#result").hide()
          } else {
            PredictResult.showResult(response.missionId.toString)
            g.reduceTime()
          }

        }
      }

    }

    form(className := "registration-form form-horizontal", onSubmit := {
      useForm.handleSubmit((data: js.Dictionary[js.Any]) => {
        println(JSON.stringify(data))
        FTool.myRunBefore()
      })
    },

      FormGroupInlineCp(useForm = useForm, names = List("sampleId"))(
        label(className := "control-label col-sm-2", "样本号:"),
        div(className := "col-sm-3",
          PureInputCp(useForm = useForm, name = "sampleId", value = data.sampleId,
            onChange = FTool.sampleIdChange, registerOptions = RegisterOptions(
              required = ValidationValueMessage(value = true, message = "样本号不能为空！"),
            )
          )
        ),
        label(className := "control-label col-sm-2", "姓名:"),
        div(className := "col-sm-3",
          PureInputCp(useForm = useForm, name = "name", value = data.name,
            onChange = FTool.nameChange,
          )
        )
      ),

      FormGroupInlineCp(useForm = useForm, names = List("age", "ast"))(
        label(className := "control-label col-sm-2", "年龄(18岁及以上):"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "age", value = data.age,
            onChange = FTool.ageChange, registerOptions = RegisterOptions(
              required = ValidationValueMessage(value = true, message = "年龄不能为空！"),
              min = ValidationValueMessage(value = 18, message = "年龄必须处于18到100之间！"),
              max = ValidationValueMessage(value = 100, message = "年龄必须处于18到100之间！"),
            )
          )
        ),
        label(className := "control-label col-sm-2", "天门冬氨酸氨基转移酶 (U/L，0～1000):"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "ast", value = data.ast,
            onChange = FTool.astChange, registerOptions = {
              val (info, min, max) = ("天门冬氨酸氨基转移酶", 0, 1000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        )
      ),

      FormGroupInlineCp(useForm = useForm, names = List("alt", "plt"))(
        label(className := "control-label col-sm-2", "丙氨酸氨基转移酶 (U/L，0～2000):"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "alt", value = data.alt,
            onChange = FTool.altChange, registerOptions = {
              val (info, min, max) = ("丙氨酸氨基转移酶", 0, 2000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        ),
        label(className := "control-label col-sm-2", "血小板计数 (10^9/L，0～1000):"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "plt", value = data.plt,
            onChange = FTool.pltChange, registerOptions = {
              val (info, min, max) = ("血小板计数", 0, 1000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        )
      ),

      FormGroupInlineCp(useForm = useForm, names = List("tyr", "tca"))(
        label(className := "control-label col-sm-2", "L-酪氨酸 (μmol/L，5～1000):"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "tyr", value = data.tyr,
            onChange = FTool.tyrChange, registerOptions = {
              val (info, min, max) = ("L-酪氨酸", 5, 1000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        ),
        label(className := "control-label col-sm-2", "牛磺胆酸 (ng/mL):"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "tca", value = data.tca,
            onChange = FTool.tcaChange, registerOptions = {
              val info = "牛磺胆酸"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
              )
            }
          )
        )
      ),

      FormGroupInlineCp(useForm = useForm, names = List("phe", "trp"))(
        label(className := "control-label col-sm-2", "苯丙氨酸（μmol/L，5～1000）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "phe", value = data.phe,
            onChange = FTool.pheChange, registerOptions = {
              val (info, min, max) = ("苯丙氨酸", 5, 1000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        ),
        label(className := "control-label col-sm-2", "色氨酸（μmol/L，5～1000）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "trp", value = data.trp,
            onChange = FTool.trpChange, registerOptions = {
              val (info, min, max) = ("色氨酸", 5, 1000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        )
      ),

      FormGroupInlineCp(useForm = useForm, names = List("valine", "ca"))(
        label(className := "control-label col-sm-2", "缬氨酸（μmol/L，5～1000）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "valine", value = data.valine,
            onChange = FTool.valineChange, registerOptions = {
              val (info, min, max) = ("缬氨酸", 5, 1000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        ),
        label(className := "control-label col-sm-2", "胆酸（μmol/L）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "ca", value = data.ca,
            onChange = FTool.caChange, registerOptions = {
              val info = "胆酸"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
              )
            }
          )
        )
      ),

      FormGroupInlineCp(useForm = useForm, names = List("met", "gca"))(
        label(className := "control-label col-sm-2", "甲硫氨酸（μmol/L，5～1000）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "met", value = data.met,
            onChange = FTool.metChange, registerOptions = {
              val (info, min, max) = ("甲硫氨酸", 5, 1000)
              val betweenInfo = s"${info}必须处于${min}到${max}之间！"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
                min = ValidationValueMessage(value = min, message = s"${betweenInfo}"),
                max = ValidationValueMessage(value = max, message = s"${betweenInfo}"),
              )
            }
          )
        ),
        label(className := "control-label col-sm-2", "甘氨氧胆酸（μmol/L）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "gca", value = data.gca,
            onChange = FTool.gcaChange, registerOptions = {
              val info = "甘氨氧胆酸"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
              )
            }
          )
        )
      ),

      FormGroupInlineCp(useForm = useForm, names = List("gcdca", "tcdca"))(
        label(className := "control-label col-sm-2", "甘氨鹅脱氧胆酸（μmol/L）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "gcdca", value = data.gcdca,
            onChange = FTool.gcdcaChange, registerOptions = {
              val info = "甘氨鹅脱氧胆酸"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
              )
            }
          )
        ),
        label(className := "control-label col-sm-2", "牛磺鹅脱氧胆酸（μmol/L）:"),
        div(className := "col-sm-3",
          NumInputCp(useForm = useForm, name = "tcdca", value = data.tcdca,
            onChange = FTool.tcdcaChange, registerOptions = {
              val info = "牛磺鹅脱氧胆酸"
              RegisterOptions(
                required = ValidationValueMessage(value = true, message = s"${info}不能为空！"),
                pattern = ValidationValueMessage(value = Tool.positiveDoubleRegexp, message = s"${info}必须为正实数！"),
              )
            }
          )
        )
      ),

      div(className := "form-group",
        div(className := "actions col-sm-offset-2 col-sm-2",
          button(`type` := "submit", className := "btn btn-primary", style := Style(width = "90%"),
            s" 运行",
          ),
        )
      ),

    )

  }


}
